Manipulating data in VFBitmaps |
Beginning with VirtualDub 1.2, it is possible to access VirtualDub's bitmap manipulation functions from external video filters. These perform a number of useful tasks such as rectangle fills, color translation, bitmap format conversions, and stretch blits. These routines are quite fast and can save you development time.
![]() |
![]() Avisynth does not support any of the VFBitmap functions that process image data, and will likely throw an error if you call any of the functions that are marked virtual. |
Initializing vtable support |
VFBitmap functions are virtual, and VirtualDub uses a bit of a hack to allow external video filters to create VFBitmaps, which requires initializing vtable pointers. To gain access to the VFBitmap vtable pointers, place
#define VDEXT_VIDEO_FILTER
#define VDEXT_MAIN
or
#define VDEXT_VIDEO_FILTER
#define VDEXT_NOTMAIN
at the top of each module. The file defining VDEXT_MAIN will declare the global variables, and the files defining VDEXT_NOTMAIN will extern them. Then, in your module initializing function, add the following line:
INITIALIZE_VTBLS;
This initializes the vtable support. After this point, you can initialize VFBitmap objects. This necessarily means you cannot declare global VFBitmaps. Because of the way VirtualDub treats module data, you also cannot declare VFBitmaps directly in a module data structure:
typedef struct MyFilterData {
VFBitmap tempbm; // this will cause page faults
} MyFilterData;
You can, however, use a pointer to a data structure that you allocate, which has an embedded VFBitmap.
VFBitmap pixel formats |
Different VFBitmap functions work on 8, 16, 24, and 32-bit bitmaps. Here is how they are defined:
depth | Layout in a dword | R mask | G mask | B mask | Description | |||||
---|---|---|---|---|---|---|---|---|---|---|
8 |
|
N/A | N/A | N/A | 8-bit paletted format | |||||
16 |
|
0x7c00 | 0x03e0 | 0x001f | 5-5-5 (16-bit) BGR | |||||
16 |
|
0xf800 | 0x07e0 | 0x001f | 5-6-5 (16-bit) BGR (seldom used) | |||||
24 |
|
0xff0000 | 0x00ff00 | 0x0000ff | 24-bit BGR format | |||||
32 |
|
0x00ff0000 | 0x0000ff00 | 0x000000ff | 32-bit BGRA format |
All pixel formats are supported by Window GDI and the DirectDraw HEL, so bitmap data is interchangeable between VirtualDub and the various Windows APIs. The brunt of most VirtualDub video filter work is done in 32-bit, but you may find the various conversion functions useful. They are significantly faster than the 16-bit GDI in Windows 95/98.
Notice that 16-bit 565 RGB has the same depth value as 16-bit 555 RGB. The 565 format is only supported by a few functions, and by default depth==16 implies the 555 format.
VFBitmap functions |
The VFBitmap functions are all virtual member functions, and so they are invoked as part of the bitmap objects.
Address32() |
Pixel *Address32(PixCoord x, PixCoord y) const;
Returns the address of a particular pixel in the bitmap, with normal y coordinates.
Inputs:
x,y: coordinates of the desired pixel
Returns:
Address of the pixel at (x,y)
Address32i() |
Pixel *Address32i(PixCoord x, PixCoord y) const;
Returns the address of a particular pixel in the bitmap, with inverted y coordinates.
Inputs:
x: x-coordinate of the desired pixel
y: inverted y-coordinate of the desired pixel
Returns:
Address of the pixel at (x, h-y-1)
PitchAlign4() |
PixOffset PitchAlign4();
Computes a dword-aligned pitch value for the current width and bit depth.
Returns:
Scanline pitch for current width and bit depth, rounded up to next 4 bytes
PitchAlign8() |
PixOffset PitchAlign8();
Computes a qword-aligned pitch value for the current width and bit depth.
Returns:
Scanline pitch for current width and bit depth, rounded up to next 8 bytes
Modulo() |
PixOffset Modulo();
Computes the gap between scanlines from the current pitch, width, and bit depth.
Returns:
Gap between scanlines, in bytes
Size() |
PixOffset Size();
Computes the total number of bytes the bitmap occupies in memory.
Returns:
Total number of bytes bitmap occupies
init(data, w, h, depth) |
VBitmap& init(void *data, PixDim w, PixDim h, int depth) throw();
Initializes a VFBitmap with the given bitmap structure and memory area.
Inputs:
data: pointer to bitmap memory block
w,h: dimensions of bitmap
depth: pixel depth of bitmap, in bits
Returns:
pointer to this VFBitmap
init(data, pBitmapInfoHeader) |
VBitmap& init(void *data, BITMAPINFOHEADER *pBitmapInfoHeader) throw();
Initializes a VFBitmap with the given bitmap structure and memory area.
Inputs:
data: pointer to bitmap memory block
pBitmapInfoHeader: pointer to Win32 bitmap description
Returns:
pointer to this VFBitmap
MakeBitmapHeader(pBitmapInfoHeader) |
void MakeBitmapHeader(BITMAPINFOHEADER *pBitmapInfoHeader) const throw();
Creates a Win32 bitmap description from a VFBitmap.
Inputs:
pBitmapInfoHeader: pointer to Win32 bitmap desc. to be filled in
Win32 BITMAPINFOHEADER structures do not allow for padding, so MakeBitmapHeader() adjusts the bitmap width to compensate. This may require manual clipping on the GDI side.
AlignTo4() |
void AlignTo4() throw();
Computes and sets the pitch, modulo, and size members of a VFBitmap for 4-byte alignment.
AlignTo8() |
void AlignTo8() throw();
Computes and sets the pitch, modulo, and size members of a VFBitmap for 8-byte alignment.
BitBlt() |
void BitBlt(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1,
PixCoord y1, PixDim dx, PixDim dy) const throw();
Copies a rectangular region from one bitmap to another.
Inputs:
x2,y2: top left corner of destination rectangle
x1,y1: top left corner of source rectangle
src: source bitmap
dx,dy: dimensions of rectangle to be copied
-1, -1 to copy largest possible rectangle
BitBlt() can do format conversion between 16, 24, and 32 bit deep bitmaps. It will also convert 8-bit paletted bitmaps to 16-, 24-, and 32-bit bitmaps.
BitBltDither() |
void BitBltDither(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1,
PixDim y1, PixDim dx, PixDim dy, bool to565) const throw();
Dithers a 32-bit deep bitmap down to 15- or 16-bit RGB.
Inputs:
x2,y2: top left corner of destination rectangle
x1,y1: top left corner of source rectangle
src: source bitmap
dx,dy: dimensions of rectangle to be copied
-1, -1 to copy largest possible rectangle
BitBltDither() uses a 4x4 ordered dither matrix. Images dithered using this routine may appear slightly darker than with BitBlt().
BitBlt565() |
void BitBlt565(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1,
PixDim y1, PixDim dx, PixDim dy) const throw();
Copies a rectangular region from a 32-bit bitmap to a 16-bit 565 bitmap.
Inputs:
x2,y2: top left corner of destination rectangle
x1,y1: top left corner of source rectangle
src: source bitmap
dx,dy: dimensions of rectangle to be copied
-1, -1 to copy largest possible rectangle
BitBltXlat1() |
bool BitBltXlat1(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1,
PixCoord y1, PixDim dx, PixDim dy, const Pixel8 *tbl) const throw();
Translates a rectangular region from one 32-bit bitmap to another with a
single lookup table for all channels.
Inputs:
x2,y2: top left corner of destination rectangle
x1,y1: top left corner of source rectangle
src: source bitmap
dx,dy: dimensions of rectangle to be translated
-1, -1 to translate largest possible rectangle
tbl: 256-byte lookup table used to translate pixels
BitBltXlat1() takes each of the three RGB channels in each pixel and runs it through the given lookup table. This allows you to do simple monochromatic effects such as brightness, contrast, and gamma correction.
BitBltXlat3() |
bool BitBltXlat3(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1,
PixCoord y1, PixDim dx, PixDim dy, const Pixel32 *tbl) const throw();
Translates a rectangular region from one 32-bit bitmap to another with a
separate lookup table for all channels.
Inputs:
x2,y2: top left corner of destination rectangle
x1,y1: top left corner of source rectangle
src: source bitmap
dx,dy: dimensions of rectangle to be translated
-1, -1 to translate largest possible rectangle
tbl: 1K-lookup table used to translate pixels
BitBltXlat3() is similar to BitBltXlat1() except that each RGB channel has its own lookup table, allowing you to use separate color ramps. The three tables are interleaved together in a 256 dword entry table in pixel format (0x00rrggbb).
StretchBltNearestFast() |
bool StretchBltNearestFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy,
const VBitmap *src, double x2, double y2, double dx1, double dy1)
const throw();
Stretches a region from one 32-bit bitmap to another using nearest neighbor
sampling.
Inputs:
x1, y1, dx, dy: position and dimensions of destination rectangle
x2, y2, dx2, dy2: position and dimensions of source rectangle
src: source bitmap
StretchBltNearestFast() will not clip either the source or destination regions and will return false if any of the regions exceed their bitmaps. You can flip the source region horizontally and vertically by making dx2 and/or dy2 negative. With horizontal flips, x2 becomes the right side of the rectangle, and with vertical flips, y2 is the bottom.
StretchBltBilinearFast() |
bool StretchBltBilinearFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy,
const VBitmap *src, double x2, double y2, double dx1, double dy1)
const throw();
Stretches a region from one 32-bit bitmap to another using bilinear sampling.
Inputs:
x1, y1, dx, dy: position and dimensions of destination rectangle
x2, y2, dx2, dy2: position and dimensions of source rectangle
src: source bitmap
StretchBltBilinearFast() will not clip either the source or destination regions and will return false if any of the regions exceed their bitmaps. You can flip the source region horizontally and vertically by making dx2 and/or dy2 negative. With horizontal flips, x2 becomes the right side of the rectangle, and with vertical flips, y2 is the bottom. StretchBltBilinearFast() always uses a 2x2 source pixel block and will give suboptimal results on shrink operations.
RectFill() |
bool RectFill(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, Pixel32 c)
const throw();
Fills a rectangular region in a 32-bit bitmap with a solid color.
Inputs:
x, y: top left corner of rectangle
dx, dy: dimensions of rectangle
-1, -1 to translate largest possible rectangle
c: color to fill with
Histogram() |
bool Histogram(PixCoord x, PixCoord y, PixCoord dx, PixCoord dy, long
*pHisto, int iHistoType) const throw();
Creates a histogram from pixels in a given source rectangle of a 16-, 24-,
or 32-bit bitmap.
Inputs:
x, y: top left corner of rectangle
dx, dy: dimensions of rectangle
-1, -1 to translate largest possible rectangle
pHisto: pointer to 256-entry histogram array to be modified
iHistoType: one of these values, to specify histogram type:
HISTO_LUMA luminance channel (21%/71%/7%)
HISTO_GRAY red, green, and blue
HISTO_RED red channel only
HISTO_GREEN green channel only
HISTO_BLUE blue channel only
Histogram() does not clear the histogram array, so you must reset it to all zero beforehand. You can also clear it once, and then call Histogram() multiple times to combine the results from several regions. In all cases except HISTO_GRAY, a value from 0-255 is added to pHisto[i] for each pixel. With HISTO_GRAY, because channel values range 0-255, values 0-765 can be added per pixel.
VirtualDub external filter SDK 1.05 | ©1999-2001 Avery Lee <phaeron@virtualdub.org> |